<?php

namespace app\index\service;

use app\common\model\Trade;
use app\index\dao\TradeDao;
use app\index\model\UM as UM;
use app\index\traits\PaymentTrait;
use ShidianUtil\Exception\DataNotExistException;
use think\exception\ValidateException;
use think\facade\Config;

/**
 * Class PaymentService
 * @package app\payment\service
 */
class PaymentService
{
    use PaymentTrait;

    // dao
    private TradeDao $tradeDao;

    public function __construct(TradeDao $tradeDao)
    {
        $this->tradeDao = $tradeDao;
    }

    /**
     * 支付订单
     * @param UM $user
     * @param int $id
     * @param array $params
     * @return Trade
     */
    public function modify(UM $user, int $id, array $params): Trade
    {
        $payMethod = $params['payMethod'] ?? null;
        if (is_blank($payMethod)) {
            throw new ValidateException('请选择支付方式');
        }

        // 支付场景
        $payMethodScene = $params['payMethodScene'] ?? '';
        if ($payMethod === PAYMENT_WXPAY && is_blank($payMethodScene)) {
            $payMethodScene = PAYMENT_WXPAY_JSAPI;
        }

        // 这里如果要修改查询，建议把查询就放到这里
        $record = Trade::field(true)->where('id', $id)->find();

        if (is_null($record)) {
            throw new DataNotExistException('该订单不存在或已被删除');
        }

        if ($user->id != $record->memberId) {
            throw new ValidateException('您不能支付该订单');
        }

        // 支付状态
        if ($record->payStatus != Trade::UNPAID) {
            if ($record->payStatus == Trade::PAID) {
                throw new ValidateException('该订单已支付成功，请重新购买');
            }
            if ($record->payStatus == Trade::CANCELLED) {
                throw new ValidateException('该订单已取消，请重新购买');
            }
            throw new ValidateException('该订单已完成，请重新购买');
        }

        // 判断该类型订单是否支持该支付方式
        $whitelist = Config::get('trade.trades.' . $record->tradeType . '.paymethods', []);
        if (!empty($whitelist)) {
            if (!in_array($payMethod, $whitelist)) {
                throw new ValidateException('该订单不支持该支付方式');
            }
        }

        // 如果更换了支付方式
        if (not_blank($record->payMethod) && $record->payMethod != $payMethod) {
            $payment = $this->getPayment($record->payMethod);
            if ($payment) {
                $payment->cancelPay($record);
            }
        }

        // 当前支付方式
        $payment = $this->getPayment($payMethod);
        if (is_null($payment)) {
            throw new ValidateException('不支持该支付方式');
        }

        // 支付方式 && 支付场景
        $record->payMethod = $payMethod;
        $record->payMethodScene = $payMethodScene;
        $record->save();

        // 根据 $payMethod 返回对应的payInfo
        $payInfo = $payment->pay($record, false);

        if ($payMethodScene === PAYMENT_WXPAY_H5 && isset($payInfo['h5_url']) && not_blank($params['redirectUrl'] ?? null)) {
            $payInfo['h5_url'] = $payInfo['h5_url'] . '&redirect_url=' . urlencode($params['redirectUrl']);
        }

        $record->payInfo = $payInfo;

        return $record;
    }

    /**
     * 读取订单详情
     * @param UM $user
     * @param int $id
     * @return Trade
     */
    public function read(UM $user, int $id): Trade
    {
        // 这里如果要修改查询，建议把查询就放到这里
        $record = Trade::where('id', $id)->find();

        if (is_null($record)) {
            throw new DataNotExistException('该订单不存在或已被删除');
        }

        if ($user->id != $record->memberId) {
            throw new ValidateException('只能查询自己的订单');
        }

        // 返回之前，主动查询支付结果并且保存
        if ($record->payStatus == Trade::UNPAID) {
            $this->getPayment($record->payMethod)->query($record);
        }

        return Trade::where('id', $id)
            ->field(['id', 'memberId', 'orderNo', 'payStatus', 'payExpTime', 'num', 'totalMoney', 'payMoney', 'tradeType'])
            ->find();
    }

    private function getTrade()
    {

    }
}
